home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 317_01 / g3sdecod.c < prev    next >
C/C++ Source or Header  |  1990-06-16  |  30KB  |  1,162 lines

  1. /*    $Id: g3sdecod.c 1.2 90/06/09 18:22:19 marking Exp $
  2.  *
  3.  NAME
  4.  *    g3sdecod.c -- decode group 3 data using nested if statements
  5.  *
  6.  TYPE
  7.  *    C procedures
  8.  *
  9.  SYNOPSIS
  10.  *    char    g3i_initialize (short image_width, short image_length);
  11.  *    char    g3i_decode (void);    -- for standard group 3
  12.  *    char    g3i_decode_T (void);    -- for TIFF g3 with no EOL chars
  13.  *
  14.  DESCRIPTION
  15.  *    In order to acquire data from the image and to return run lengths and
  16.  *    new line information, these routines invoke procedures provided by the
  17.  *    caller. These caller-provided procedures are invoked throught pointers
  18.  *    which have been stuffed by the caller with the procedure addresses.
  19.  *    To acquire a new data byte, g3i_decode () and g3i_decode_T () call
  20.  *    (*p_decode_next_byte) (). To report the decoding of a black or white
  21.  *    run, the routines (*p_decode_black) () or (*p_decode_white) () are
  22.  *    called.
  23.  *
  24.  RETURNS
  25.  *    Initialization always returns zero.
  26.  *
  27.  *    For decoding,
  28.  *        0    end of image reached
  29.  *        -1    on error (bad data)
  30.  *    The decode loop will be prematurely terminated if decode_return is
  31.  *    set to not zero, and the value of decode_return will be returned.
  32.  *    No code here does this, but it might be useful under certain
  33.  *    circumstances.
  34.  *
  35.  LEGAL
  36.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  37.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  38.  *
  39.  *    License is granted by the copyright holder to distribute and use this
  40.  *    code without payment of royalties or the necessity of notification as
  41.  *    long as this notice (all the text under "LEGAL") is included.
  42.  *
  43.  *    Reference: $Id: g3sdecod.c 1.2 90/06/09 18:22:19 marking Exp $
  44.  *
  45.  *    This program is offered without any warranty of any kind. It includes
  46.  *    no warranty of merchantability or fitness for any purpose. Testing and
  47.  *    suitability for any use are the sole responsibility of the user.
  48.  * 
  49.  HISTORY
  50.  *    $Log:    g3sdecod.c $
  51.  * Revision 1.2  90/06/09  18:22:19  marking
  52.  * clean up comments for release
  53.  * 
  54.  * Revision 1.1  89/06/30  17:00:00  marking
  55.  * Initial revision
  56.  * 
  57.  *
  58.  NOTES
  59.  *
  60.  PORTABILITY
  61.  *    Tested using Microsoft C 5.1. Some memory models may not work due to
  62.  *    the large decoding arrays.
  63.  *
  64.  *    There is a non-portable use of "global" variables in the file g3g4.h,
  65.  *    about which a minority of compilers will justifiably complain. Certain
  66.  *    variables are declared in g3g4.h without extern keywords. Strictly
  67.  *    speaking, they should be declared extern in all but one module, but
  68.  *    that would require complication of g3g4.h. If it gets past your
  69.  *    compiler and linker, you can probably ignore it.
  70.  *
  71.  SEE ALSO
  72.  *    g4sdecod.c -- decode group 4 image using nested if statements
  73.  *
  74.  INFORMATION
  75.  *    Although there is no support offered with this program, the author will
  76.  *    endeavor to correct errors. Updates will also be made available from
  77.  *    time to time.
  78.  *
  79.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  80.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  81.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  82.  *
  83.  *    Also beginning in July 1990, this code will be archived at the
  84.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  85.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  86.  *    "public", system "bbs", and password "public".
  87.  *
  88.  *    This code is also available from the C Users Group in volume 317.
  89.  *
  90.  */
  91.  
  92. #include "g3g4.h"
  93.  
  94. /* #define TRACE 1 */
  95. #define TRACE_BEGIN 0
  96. #define TRACE_END 30000
  97.  
  98. static short bit_number, code_byte;
  99. static unsigned char color, current_row, mode, next_state;
  100. static short column_limit, row_limit;
  101. static short row_number = 0, column_number;
  102.  
  103. extern unsigned char horiz_mode [] [256];
  104. extern unsigned char horiz_mode_next_state [] [256];
  105.  
  106. static short new_row (void);
  107. static short decode_white_run (void);
  108. static short decode_black_run (void);
  109. static short decode_white_word (void);
  110. static short decode_black_word (void);
  111. static char next_bit (void);
  112.  
  113. static char decode_return;
  114.  
  115. /* g3i_decode () successively invokes (*p_decode_next_byte) () for each byte
  116.    of the encoded image, and calls (*p_decode_white) () or (*p_decode_black) ()
  117.    as required to return the image contents on a run-by-run basis. */
  118.  
  119. char g3i_decode ()
  120. {
  121.   short runlength;
  122.   while (!decode_return)
  123.   {
  124.     if (color == WHITE)
  125.     {
  126.       runlength = decode_white_run ();
  127.       if (runlength == -2) return (-1);
  128.       else if (runlength == -1)
  129.       {
  130.     if (new_row ()) return (0);
  131.       }
  132.       else
  133.       {
  134.     column_number += runlength;
  135.     (*p_decode_white) ((short) runlength);
  136.     color = BLACK;
  137.       }
  138.     }
  139.     else
  140.     {
  141.       runlength = decode_black_run ();
  142.       if (runlength == -2) return (-1);
  143.       else if (runlength == -1)
  144.       {
  145.     if (new_row ()) return (0);
  146.       }
  147.       else
  148.       {
  149.     column_number += runlength;
  150.     (*p_decode_black) ((short) runlength);
  151.     color = WHITE;
  152.       }
  153.     }
  154.   }
  155.   return (decode_return);
  156. }
  157.  
  158. /* special version for TIFF files with no EOL characters */
  159. char g3i_decode_T ()
  160. {
  161.   short runlength;
  162.   while (!decode_return)
  163.   {
  164.     if (color == WHITE)
  165.     {
  166.       runlength = decode_white_run ();
  167.       if (runlength == -2) return (-1);
  168.       else if (runlength == -1)
  169.       {
  170.     if (new_row ()) return (0);
  171.       }
  172.       else
  173.       {
  174.     column_number += runlength;
  175.     (*p_decode_white) ((short) runlength);
  176.     color = BLACK;
  177.     if (column_number >= column_limit)
  178.     {
  179.       if (new_row ()) return (0);
  180.       bit_number = 0;
  181.     }
  182.       }
  183.     }
  184.     else
  185.     {
  186.       runlength = decode_black_run ();
  187.       if (runlength == -2) return (-1);
  188.       else if (runlength == -1)
  189.       {
  190.     if (new_row ()) return (0);
  191.       }
  192.       else
  193.       {
  194.     column_number += runlength;
  195.     (*p_decode_black) ((short) runlength);
  196.     color = WHITE;
  197.     if (column_number >= column_limit)
  198.     {
  199.       if (new_row ()) return (0);
  200.       bit_number = 0;
  201.     }
  202.       }
  203.     }
  204.   }
  205.   return (decode_return);
  206. }
  207.  
  208. /* g3i_initialize () is called to set up to decode a new image.  All of the
  209.    static data (flags, etc) for g3i_decode () are initialized, allowing the
  210.    decoding of multiple images as long as g3i_initialize () is
  211.    called before each. */
  212. char g3i_initialize (short image_width, short image_length)
  213. {
  214.   color = WHITE;
  215.   bit_number= 0;
  216.   column_limit = image_width;
  217.   row_limit = image_length;
  218.   row_number = 0;
  219.   column_number = 0;
  220.   decode_return = 0;
  221.   return (0);
  222. }
  223.  
  224. static short new_row ()
  225. {
  226.   if (column_number)
  227.   {
  228.     (*p_decode_new_row) ();
  229.     color = WHITE;
  230.     if (++row_number >= row_limit) return (-1);
  231.     column_number = 0;
  232.     return (0);
  233.   }
  234.   else return (0);
  235. }
  236.  
  237. static char next_bit (void)
  238. {
  239.   char value;
  240.   static unsigned char decode_mask [8] =
  241.     { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  242.   if (!bit_number) code_byte = (*p_decode_next_byte) ();
  243.   if ((unsigned char) code_byte & decode_mask [bit_number]) value = 1;
  244.   else value = 0;
  245.   if (++bit_number > 7) bit_number = 0;
  246.   return (value);
  247. }
  248.  
  249. /*
  250.  *    return the length of the next run, assumed to be black
  251.  */
  252.  
  253. static short decode_black_run ()
  254. {
  255.   short cumulative = 0, code_value;
  256.   for (;;)
  257.   {
  258.     code_value = decode_black_word ();
  259.     cumulative += code_value;
  260.     if (code_value < 0) return (code_value);
  261.     if (code_value < 64) return (cumulative);
  262.   }
  263. }
  264.  
  265. static short decode_black_word ()
  266. {
  267.   if (next_bit ()) /* 1... */
  268.   {
  269.     if (next_bit ()) /* 11 */ return (2);
  270.     else /* 10 */ return (3);
  271.   }
  272.   else /* 0... */
  273.   {
  274.     if (next_bit ()) /* 01... */
  275.     {
  276.       if (next_bit ()) /* 011 */ return (4);
  277.       else /* 010 */ return (1);
  278.     }
  279.     else /* 00... */
  280.     {
  281.       if (next_bit ()) /* 001... */
  282.       {
  283.     if (next_bit ()) /* 0011 */ return (5);
  284.     else /* 0010 */ return (6);
  285.       }
  286.       else /* 000... */
  287.       {
  288.     if (next_bit ()) /* 0001... */
  289.     {
  290.       if (next_bit ()) /* 0001 1 */ return (7);
  291.       else /* 0001 0... */
  292.       {
  293.         if (next_bit ()) /* 0001 01 */ return (8);
  294.         else /* 0001 00 */ return (9);
  295.       }
  296.     }
  297.     else /* 0000... */
  298.     {
  299.       if (next_